package com.yanqu.road.server.manger.banquet;

import com.yanqu.road.dao.impl.cross.banquet.UserAutoBanquetActivityDataDaoImpl;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.banquet.BanquetInfo;
import com.yanqu.road.entity.banquet.UserCrossBanquetData;
import com.yanqu.road.entity.banquet.autoopen.BanquetAutoOpenRecord;
import com.yanqu.road.entity.banquet.autoopen.BanquetAutoOpenSettleMember;
import com.yanqu.road.entity.banquet.autoopen.UserAutoBanquetActivityData;
import com.yanqu.road.entity.enums.eBanquetInfoType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eMailType;
import com.yanqu.road.entity.enums.eSkillType;
import com.yanqu.road.entity.log.LogBanquetAutoOpenEnd;
import com.yanqu.road.entity.player.UserInfo;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.pb.banquet.BanquetProto;
import com.yanqu.road.pb.banquet.CrossBanquetProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.banquet.BanquetModule;
import com.yanqu.road.server.gameplayer.module.player.BeautyModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.logic.mail.MailManager;
import com.yanqu.road.server.manger.MultipleLanguageMgr;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.math.BigInteger;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class CrossBanquetAutoOpenMgr extends TempMgr {

    private static Logger logger = LogManager.getLogger(CrossBanquetAutoOpenMgr.class.getName());

    //同时只有一个活动
    private static Map<Long, UserAutoBanquetActivityData> userAutoBanquetActivityDataMap = new ConcurrentHashMap<>();

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        ActivityInfo activityInfo = NormalActivityMgr.getRunningCrossBanquetRankActivity();
        //必须是跨服争霸，就是三个区服的才能开宴会
        if(activityInfo != null && activityInfo.getServerIdList().size() > 2){
            userAutoBanquetActivityDataMap = new UserAutoBanquetActivityDataDaoImpl().getUserAutoBanquetActivityData(activityInfo.getActivityId());
        }
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }

    @Override
    public boolean save() {
        for (Map.Entry<Long, UserAutoBanquetActivityData> entry : userAutoBanquetActivityDataMap.entrySet()) {
            UserAutoBanquetActivityData data = entry.getValue();
            if(data.isInsertOption()){
                new UserAutoBanquetActivityDataDaoImpl().add(data);
            }else if(data.isUpdateOption()){
                new UserAutoBanquetActivityDataDaoImpl().update(data);
            }
        }
        return true;
    }

    /**
     * 设置
     * @param opt 0 自动开宴；1 停止
     * @param type 宴会类型或者宴会id（50001|50002）
     * @param times 次数
     * @return
     */
    public static int autoOpenSetting(GamePlayer player, int opt, int type, int times) {
        ActivityInfo activityInfo = NormalActivityMgr.getRunningCrossBanquetRankActivity();
        //必须是跨服争霸，就是三个区服的才能开宴会
        if(activityInfo == null || activityInfo.getServerIdList().size() <= 2){
            return GameErrorCode.E_BANQUET_CROSS_RANK_ACTIVITY_OVER;
        }

        if(opt != 0 && opt != 1){
            return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
        }
        if(opt == 0 && !ActivityMgr.activityInTime(activityInfo)){
            return GameErrorCode.E_BANQUET_ACTIVITY_NO_IN_TIME;
        }
        //宴会类型判断
        List<Integer> idList = new ArrayList<>();
        idList.add(eBanquetInfoType.CrossUserBanquet1.getValue());
        idList.add(eBanquetInfoType.CrossUserBanquet2.getValue());
        if(!idList.contains(type)){
            return GameErrorCode.E_BANQUET_AUTO_OPEN_TYPE_ERROR;
        }

        BanquetInfo banquetInfo = BanquetConfigMgr.getBanquetInfo(type);
        if(banquetInfo == null){
            return GameErrorCode.E_BANQUET_INFO_ERROR;
        }

        if(opt == 1){
            return cancelAutoOpenSetting(player, activityInfo, banquetInfo);
        }

        long userId = player.getUserId();
        Object lock = getUserLocker(userId);
        synchronized (lock){
            boolean isNew = false;
            UserAutoBanquetActivityData activityData = userAutoBanquetActivityDataMap.get(userId);
            if(activityData == null || activityInfo.getActivityId() != activityData.getActivityId()){
                activityData = new UserAutoBanquetActivityData();
                activityData.setActivityId(activityInfo.getActivityId());
                activityData.setUserId(userId);
                activityData.setInsertOption();
                activityData.setBanquetType(type);
                isNew = true;
            }else {
                //类型不对
                if(activityData.getBanquetType() != type && !StringUtils.isNullOrEmpty(activityData.getPreReduceGoods())){
                    return GameErrorCode.E_BANQUET_AUTO_OPEN_TYPE_DIFFERENT;
                }
            }

            //扣道具
            Property consume = PropertyHelper.parseStringToProperty(banquetInfo.getOpenConsume());
            consume.rideProperty(times);
            if(!player.getModule(CurrencyModule.class).removeCurrency(consume, eLogMoneyType.Banquet, eLogMoneyType.BanquetAutoOpenPreConsume)){
                return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
            }

            //原来道具
            Property old = PropertyHelper.parseStringToProperty(activityData.getPreReduceGoods());
            if(old == null){
                old = consume;
            }else {
                old.addProperty(consume);
            }
            if(StringUtils.isNullOrEmpty(activityData.getPreReduceGoods())){
                activityData.setBanquetType(type);
                activityData.setCurTimes(0);
                activityData.setAllTimes(times);
            }else {
                activityData.setAllTimes(times + activityData.getAllTimes());
            }
            activityData.setPreReduceGoods(PropertyHelper.parsePropertyToString(old));


            if(isNew){
                userAutoBanquetActivityDataMap.put(userId, activityData);
            }

            BanquetProto.AutoBanquetSettingForActivityRespMsg.Builder clientMsg = BanquetProto.AutoBanquetSettingForActivityRespMsg.newBuilder();
            clientMsg.setRet(0);
            BanquetProto.AutoBanquetSettingInfoTemp.Builder builder = getActivityDataBuilder(activityData);
            clientMsg.setSetting(builder);

            //直接调用一次开宴会检测
            check(activityData);

            player.sendPacket(Protocol.U_BANQUET_ACTIVITY_AUTO_SETTING, clientMsg);
        }

        return 0;
    }

    private static BanquetProto.AutoBanquetSettingInfoTemp.Builder getActivityDataBuilder(UserAutoBanquetActivityData activityData) {
        BanquetProto.AutoBanquetSettingInfoTemp.Builder builder = BanquetProto.AutoBanquetSettingInfoTemp.newBuilder();
        builder.setBanquetType(activityData.getBanquetType());
        builder.setAllTimes(activityData.getAllTimes());
        builder.setCurTimes(activityData.getCurTimes());
        return builder;
    }

    //取消自动
    private static int cancelAutoOpenSetting(GamePlayer player, ActivityInfo activityInfo, BanquetInfo banquetInfo) {
        long userId = player.getUserId();
        Object lock = getUserLocker(userId);
        synchronized (lock){
            UserAutoBanquetActivityData activityData = userAutoBanquetActivityDataMap.get(userId);
            //没有当前活动的自动开宴
            if(activityData == null || StringUtils.isNullOrEmpty(activityData.getPreReduceGoods()) || activityData.getActivityId() != activityInfo.getActivityId()){
                BanquetProto.AutoBanquetSettingForActivityRespMsg.Builder clientMsg = BanquetProto.AutoBanquetSettingForActivityRespMsg.newBuilder();
                clientMsg.setRet(0);
                BanquetProto.AutoBanquetSettingInfoTemp.Builder builder = getActivityDataBuilder(activityData);
                clientMsg.setSetting(builder);
                player.sendPacket(Protocol.U_BANQUET_ACTIVITY_AUTO_SETTING, clientMsg);
                return 0;
            }

            backGoods(player.getUserInfo(), userId, activityData);

            BanquetProto.AutoBanquetSettingForActivityRespMsg.Builder clientMsg = BanquetProto.AutoBanquetSettingForActivityRespMsg.newBuilder();
            clientMsg.setRet(0);
            BanquetProto.AutoBanquetSettingInfoTemp.Builder builder = getActivityDataBuilder(activityData);
            clientMsg.setSetting(builder);
            player.sendPacket(Protocol.U_BANQUET_ACTIVITY_AUTO_SETTING, clientMsg);

        }
        return 0;
    }

    /**
     * 返还道具
     */
    private static boolean backGoods(UserInfo player, long userId, UserAutoBanquetActivityData activityData) {
        //回收
        Property back = PropertyHelper.parseStringToProperty(activityData.getPreReduceGoods());
        if(back.isNothing()){
            logger.info("userId {}, activityId {} 自动开宴会奖励返还异常 {}", userId, activityData.getActivityId(), activityData.getPreReduceGoods());
            return false;
        }

        int times = activityData.getCurTimes();
        int allTimes = activityData.getAllTimes();
        activityData.setPreReduceGoods("");
        activityData.setAllTimes(0);
        activityData.setCurTimes(0);
        //返还道具
        //发邮件
        MailManager.sendMail(player.getUserId(), 0L, eMailType.SYSTEM.getValue(), PropertyHelper.parsePropertyToString(back),
                StringUtils.format(MultipleLanguageMgr.getContent(MailManager.BANQUET_AUTO_OPEN_ITEM_RETURN, player.getLanguage()), times, allTimes - times),
                MultipleLanguageMgr.getContent(MailManager.BANQUET_AUTO_OPEN, player.getLanguage()),
                new Date());
        return true;
    }


    private static int offLineCheckTimes = 0;

    /**
     * 检测
     */
    public static void autoOpenCheck(){
        offLineCheckTimes++;
        if(offLineCheckTimes >= 4){
            offLineCheckTimes = 0;
        }
        int checkNum = 0;
        for (Map.Entry<Long, UserAutoBanquetActivityData> entry : userAutoBanquetActivityDataMap.entrySet()) {
            try {
                UserAutoBanquetActivityData data = entry.getValue();
                GamePlayer player = GamePlayerMgr.getOnlinePlayer(data.getUserId());
                //离线玩家，降低检查频率
                if(player == null && offLineCheckTimes != 0){
                    continue;
                }
                boolean ret = check(data);
                if(ret){
                    checkNum++;
                }
                if(checkNum >= 30){
                    logger.info("autoOpenCheck num:{}", checkNum);
                    break;
                }
            }catch (Exception e){
                logger.info("autoOpenCheck error:", e);
            }
        }
        if(checkNum > 0){
            logger.info("autoOpenCheck num:{}", checkNum);
        }
    }

    /**
     * 返回是否有跨服交互
     */
    private static boolean check(UserAutoBanquetActivityData data) {
        long userId = data.getUserId();
        Object lock = getUserLocker(userId);
        synchronized (lock){

            //保留最新400条
            int limitSize = 400;
            if(data.getOpenRecordList().size() > limitSize){
                int size = data.getOpenRecordList().size();
                while (data.getOpenRecordList().size() > limitSize){
                    data.getOpenRecordList().remove(0);
                }
                data.setUpdateOption();
                getLogger().info("remove {} 自动开宴历史记录 {}", userId, size - limitSize);
            }

            int recordSize = data.getOpenRecordList().size();
            if(recordSize > 0){
                BanquetAutoOpenRecord record = data.getOpenRecordList().get(recordSize - 1);
                //最后一场已开启
                if(record.getState() == 0){
                    //检测开启结果
                    if(DateHelper.getCurrentSecond() - record.getAdTm() > DateHelper.MINUTE_SECONDS && record.getAdTm() > 0){
                        logger.info("playerId {} activityId {} 自动开宴会 {}， 超过1分钟没有结果", userId, data.getActivityId(), record.getAdTm());
                        //补偿
                        if(!StringUtils.isNullOrEmpty(record.getbUid())){
                            UserCrossBanquetData banquetData = CrossBanquetMgr.getBanquet(record.getbUid());
                            if(banquetData != null){
                                //补偿，玩家不用一定在线
                                updateAutoOpenSuccess(userId, banquetData.getBanquetId(), banquetData.getOpenTime(), banquetData.getOverTime(), banquetData.getType());
                                logger.info("playerId {} activityId {} 自动开宴会 {}， 进行补偿更新", userId, data.getActivityId(), record.getbUid());
                            }
                        }else {
                            if(DateHelper.getCurrentSecond() - record.getAdTm() > DateHelper.MINUTE_SECONDS * 60){
                                //跨服挂掉，补偿
                                logger.info("playerId {} activityId {} 自动开宴会 {}， 已经超过60分钟没有结果", userId, data.getActivityId(), record.getAdTm());
                                ActivityInfo activityInfo = NormalActivityMgr.getRunningCrossBanquetRankActivity();
                                if(ActivityMgr.activityInTime(activityInfo) && CrossBanquetMgr.canOpenBanquet(data.getUserId(), data.getBanquetType()) && activityInfo.getActivityId() == data.getActivityId()) {
                                    //开启宴会请求
                                    record.setReTs(record.getReTs() + 1);
                                    data.setUpdateOption();
                                    sendOpen(data, activityInfo, record);
                                    return true;
                                }
                            }
                        }
                    }
                    return false;
                }

                if(record.getState() == -1){
                    //如果自动开启失败，暂停10分钟
                    ActivityInfo activityInfo = NormalActivityMgr.getRunningCrossBanquetRankActivity();
                    if(ActivityMgr.activityInTime(activityInfo)){
                        //10分钟后重开（限制频率）
                        if(DateHelper.getCurrentSecond() - record.getAdTm() > 10 * DateHelper.MINUTE_SECONDS && record.getAdTm() > 0) {
                            sendOpen(data, activityInfo, record);
                            logger.info("playerId {} activityId {} 自动开宴会 {}， 重试", userId, data.getActivityId(), record.getTy());
                            return true;
                        }
                    }
                }

                //最后一场是否结束、可以领奖
                if(record.getState() == 1){
                    UserCrossBanquetData banquetData = CrossBanquetMgr.getBanquet(record.getbUid());
                    if(banquetData != null && !banquetData.isSendReward() && CrossBanquetMgr.isBanquetOver(banquetData.getBanquetId())){
                        ActivityInfo activityInfo = NormalActivityMgr.getRunningCrossBanquetRankActivity();
                        //跨服挂了
                        if(banquetData.getPopularity() == 0 && ActivityMgr.activityInTime(activityInfo) && DateHelper.getCurrentSecond() - record.getAdTm() > DateHelper.HOUR_SECONDS * 5
                                && CrossBanquetMgr.canOpenBanquet(data.getUserId(), data.getBanquetType())){
                            record.setReTs(record.getReTs() + 1);
                            record.setState(0);
                            record.setbUid("");
                            data.setUpdateOption();
                            sendOpen(data, activityInfo, record);
                            logger.info("playerId {} activityId {} 自动开宴会 {}， 已经结束没有结果，进行重新开启", userId, data.getActivityId(), record.getAdTm());
                            return true;
                        }
                        //(要防止重复请求)
                        sendGetReward(userId, banquetData.getBanquetId());
                        return true;
                    }
                    //防止更新不到的补偿
                    if(banquetData != null && banquetData.isSendReward()){
                        record.setState(2);
                        data.setUpdateOption();
                        logger.info("playerId {} activityId {}, {} 补偿领奖状态", data.getUserId(), data.getActivityId(), record.getbUid());
                        return true;
                    }
                    return false;
                }
            }

            //是否可以开下一场
            if(StringUtils.isNullOrEmpty(data.getPreReduceGoods())){
                return false;
            }

            ActivityInfo activityInfo = NormalActivityMgr.getRunningCrossBanquetRankActivity();
            //没有活动，活动不一致，活动领奖期
            if(activityInfo == null || activityInfo.getActivityId() != data.getActivityId() || !ActivityMgr.activityInTime(activityInfo)){
                //返还道具
                GamePlayer player = GamePlayerMgr.getOnlinePlayer(data.getUserId());
                if(player != null){
                    backGoods(player.getUserInfo(), player.getUserId(), data);
                }else {
                    UserInfo userInfo = UserMgr.getUserInfo(data.getUserId());
                    if(userInfo != null) {
                        backGoods(userInfo, userInfo.getUserId(), data);
                    }
                }
                return false;
            }

            BanquetInfo banquetInfo = BanquetConfigMgr.getBanquetInfo(data.getBanquetType());
            if(banquetInfo == null){
                return false;
            }

            if(!ActivityMgr.activityInTime(activityInfo)){
                return false;
            }

            //是否有同类型
            if(!CrossBanquetMgr.canOpenBanquet(data.getUserId(), data.getBanquetType())){
                return false;
            }

            //开启消耗
            Property old = PropertyHelper.parseStringToProperty(data.getPreReduceGoods());
            Property consume = PropertyHelper.parseStringToProperty(banquetInfo.getOpenConsume());
            for (Map.Entry<Integer, BigInteger> entry : consume.getGoods().entrySet()) {
                if(old.getCountByGoodsId(entry.getKey()).compareTo(entry.getValue()) < 0){
                    logger.info("userId {} auto open type {}, 材料不足 ：{}={}", data.getUserId(), data.getBanquetType(), entry.getKey(), entry.getValue());
                    return false;
                }
                old.removeProperty(entry.getKey(), entry.getValue());
            }
            data.setPreReduceGoods(PropertyHelper.parsePropertyToString(old));
            data.setCurTimes(1 + data.getCurTimes());

            //记录
            BanquetAutoOpenRecord openRecord = new BanquetAutoOpenRecord();
            openRecord.setbUid("");
            openRecord.setTy(data.getBanquetType());
            openRecord.setAdTm(DateHelper.getCurrentSecond());
            data.getOpenRecordList().add(openRecord);
            data.setUpdateOption();

            //开启宴会请求
            sendOpen(data, activityInfo, openRecord);
            return true;
        }
    }

    private static void sendGetReward(long userId, String banquetId) {
        //发起领奖
        GamePlayer player = GamePlayerMgr.getPlayer(userId);
        if(player != null) {
            //from cmd
            //门客技能加成
            int beautiesSkillAdd = BanquetMgr.getBanquetOpenSkillAddition(player);

            CrossBanquetProto.CrossBanquetGetRewardReq.Builder msg = CrossBanquetProto.CrossBanquetGetRewardReq.newBuilder();
            msg.setBeautiesSkillAdd(beautiesSkillAdd);
            msg.setAutoOpen(true);
            msg.setBanquetId(banquetId);
            YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_BANQUET_USER_REWARD, msg);
            GamePlayerMgr.sendPacket(player.getUserId(), pbMsg);
        }
    }

    private static void sendOpen(UserAutoBanquetActivityData data, ActivityInfo activityInfo, BanquetAutoOpenRecord openRecord) {
        try{
            //拉起用户
            GamePlayer player = GamePlayerMgr.getPlayer(data.getUserId());
            if(player != null){
                if(openRecord.getState() == -1){
                    //重试次数（记录）
                    openRecord.setReTs(openRecord.getReTs() + 1);
                    //重开
                    openRecord.setState(0);
                    logger.info("userId {} retry auto open type {}，时间：{}", player.getUserId(), openRecord.getTy(), openRecord.getAdTm());
                    //设置
                    openRecord.setAdTm(DateHelper.getCurrentSecond());
                }

                //复制cmd
                BanquetModule banquetModule = player.getModule(BanquetModule.class);
                //开榜重置礼物接受设置,同个活动开始时间内不重置
                int type = openRecord.getTy();
                if (banquetModule.settingCanReset(type, activityInfo.getBeginTime())) {
                    banquetModule.updateUserBanquetSetting(type,"");
                }
                banquetModule.updateUserBanquetSettingBanquetId(type, "");

                CrossBanquetProto.PreOpenCrossBanquetReq.Builder msg = CrossBanquetProto.PreOpenCrossBanquetReq.newBuilder();
                msg.setInvitationId("");
                msg.setInvitationInfo("");
                msg.setType(type);
                msg.setAutoOpen(true);
                msg.setServerListStr(activityInfo.getServerListStr2());
                msg.setPlayerBaseData(PlayerBasePb.parsePlayerBaseTempMsg(UserMgr.parseUserBaseInfo(player.getUserInfo(), GameServer.getInstance().getServerId())));
                msg.setGiftTypeAccept(banquetModule.getUserBanquetSettingGiftTypeAccept(type));
                YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_CROSS_PRE_OPEN_BANQUET, msg);
                GamePlayerMgr.sendPacket(player.getUserId(), pbMsg);

            }else {
                getLogger().info("userId {} auto open fail:", data.getUserId());
            }
        }catch (Exception e){
            getLogger().info("userId {} auto open error:", data.getUserId(), e);
        }
    }

    public static void preUpdateAutoOpenFail(GamePlayer player, int type) {
        long userId = player.getUserId();
        Object lock = getUserLocker(userId);
        synchronized (lock) {
            UserAutoBanquetActivityData activityData = userAutoBanquetActivityDataMap.get(userId);
            if (activityData == null) {
                return;
            }

            int recordSize = activityData.getOpenRecordList().size();
            if (recordSize == 0) {
                return;
            }
            BanquetAutoOpenRecord record = activityData.getOpenRecordList().get(recordSize - 1);

            if(record.getState() == 0 && record.getTy() == type){
                record.setState(-1);
                logger.info("userId {} pre auto open type {}, 失败", player.getUserId(), type);
                activityData.setUpdateOption();
            }
        }
    }

    public static void preUpdateAutoOpenSuccess(GamePlayer player, String banquetId, int type) {
        long userId = player.getUserId();
        Object lock = getUserLocker(userId);
        synchronized (lock) {
            UserAutoBanquetActivityData activityData = userAutoBanquetActivityDataMap.get(userId);
            if (activityData == null) {
                return;
            }
            int recordSize = activityData.getOpenRecordList().size();
            if (recordSize == 0) {
                return;
            }
            BanquetAutoOpenRecord record = activityData.getOpenRecordList().get(recordSize - 1);

            if ((record.getState() == 0 || record.getState() == -1) && record.getTy() == type && StringUtils.isNullOrEmpty(record.getbUid())) {
                record.setbUid(banquetId);
                logger.info("userId {} pre auto open type {}, 成功, banquetId {}", player.getUserId(), type, banquetId);
                if(record.getState() == -1){
                    record.setState(0);
                }
                activityData.setUpdateOption();
            }
        }
    }

    /**
     * 开宴成功（更新时，玩家不用一定在线）
     */
    public static void updateAutoOpenSuccess(long userId, String banquetId, long openTime, long overTime, int type) {
        Object lock = getUserLocker(userId);
        synchronized (lock){
            UserAutoBanquetActivityData activityData = userAutoBanquetActivityDataMap.get(userId);
            if(activityData == null){
                return;
            }
            int recordSize = activityData.getOpenRecordList().size();
            if(recordSize == 0){
                return;
            }
            BanquetAutoOpenRecord record = activityData.getOpenRecordList().get(recordSize - 1);

            if((record.getState() == 0 || record.getState() == -1)&& record.getTy() == type && (banquetId.equals(record.getbUid()) || StringUtils.isNullOrEmpty(record.getbUid()))){
                record.setbUid(banquetId);
                record.setTm((int)(openTime/1000));
                record.setState(1);
                activityData.setUpdateOption();
                logger.info("userId:{},activityId:{}, banquetId:{}, 自动开宴成功！！！", userId, activityData.getActivityId(), record.getbUid());
            }else {
                logger.info("updateAutoOpenSuccess error: banquetId {},openTime:{},type:{}. record state {}, type {}, addTime:{}",
                        banquetId, openTime, type, record.getState(), record.getTy(), record.getAdTm());
            }
        }
        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
        if(player != null && player.getLastPingTime() > 0 && (System.currentTimeMillis() - player.getLastPingTime() < 15 * 1000)) {
            syncAutoBanquetSettingInfo(player);
        }
    }

    /**
     * 领奖成功
     */
    public static void updateAutoRewardSuccess(GamePlayer player, BanquetProto.BanquetGetRewardTempMsg tempMsg, long popularity, long integral) {
        String banquetId = tempMsg.getBanquetId();
        long userId = player.getUserId();
        Object lock = getUserLocker(userId);
        synchronized (lock) {
            UserAutoBanquetActivityData activityData = userAutoBanquetActivityDataMap.get(userId);
            if (activityData == null) {
                return;
            }
            int recordSize = activityData.getOpenRecordList().size();
            if (recordSize == 0) {
                return;
            }
            BanquetAutoOpenRecord record = activityData.getOpenRecordList().get(recordSize - 1);
            if(record.getState() == 1 && record.getbUid().equals(banquetId)){
                record.setState(2);
                record.setJf((int)integral);
                record.setRq((int)popularity);

                List<BanquetAutoOpenSettleMember> list = new ArrayList<>();
                for (BanquetProto.MemberRewardTempMsg rewardTempMsg : tempMsg.getMemberRewardListList()) {
                    BanquetAutoOpenSettleMember settle = new BanquetAutoOpenSettleMember();
                    if(rewardTempMsg.hasPlayerBaseData()) {
                        settle.setN(rewardTempMsg.getPlayerBaseData().getNickName());
                    }else {
                        settle.setN("一登大师");
                    }
                    settle.setRq((int)rewardTempMsg.getPopularity());
                    list.add(settle);
                }
                //activityData.getSettleMap().put(record.getbUid(), list);
                activityData.setUpdateOption();
                logger.info("userId:{},activityId:{}, banquetId:{}, 自动领取成功！！！", userId, activityData.getActivityId(), record.getbUid());

                AutoLogMgr.add(new LogBanquetAutoOpenEnd(activityData.getActivityId(), activityData.getUserId(), record.getbUid(), record.getJf(), record.getRq(), record.getTy()));
            }
        }
    }

    public static int getAutoOpenRecord(GamePlayer player){
        long userId = player.getUserId();
        UserAutoBanquetActivityData activityData = userAutoBanquetActivityDataMap.get(userId);
        BanquetProto.AutoBanquetOpenRecordRespMsg.Builder clientMsg = BanquetProto.AutoBanquetOpenRecordRespMsg.newBuilder();
        clientMsg.setRet(0);
        if(activityData != null && activityData.getOpenRecordList().size() > 0){
            for (int i = 0; i < activityData.getOpenRecordList().size(); i++) {
                BanquetAutoOpenRecord record = activityData.getOpenRecordList().get(i);
                if(record.getState() > 1){
                    BanquetProto.AutoBanquetOpenRecordTemp.Builder builder = BanquetProto.AutoBanquetOpenRecordTemp.newBuilder();
                    builder.setRenQi(record.getRq());
                    builder.setJiFen(record.getJf());
                    builder.setType(record.getTy());
                    clientMsg.addRecord(builder);
                }
            }
        }
        player.sendPacket(Protocol.U_BANQUET_ACTIVITY_AUTO_RECORD, clientMsg);
        return 0;
    }

    public static int getAutoOpenSettleReward(GamePlayer player){
        long userId = player.getUserId();
        UserAutoBanquetActivityData activityData = userAutoBanquetActivityDataMap.get(userId);
        BanquetProto.AutoBanquetGetSettleInfoRespMsg.Builder clientMsg = BanquetProto.AutoBanquetGetSettleInfoRespMsg.newBuilder();
        clientMsg.setRet(0);
        //加锁
        synchronized (getUserLocker(userId)) {
            if (activityData != null && activityData.getOpenRecordList().size() > 0) {
                for (int i = 0; i < activityData.getOpenRecordList().size(); i++) {
                    BanquetAutoOpenRecord record = activityData.getOpenRecordList().get(i);
                    if (record.getState() == 2) {
                        record.setState(3);
                    }
                    List<BanquetAutoOpenSettleMember> list = activityData.getSettleMap().get(record.getbUid());
                    BanquetProto.AutoBanquetGetSettleInfoTemp.Builder settleBuild = BanquetProto.AutoBanquetGetSettleInfoTemp.newBuilder();
                    if (list != null) {
                        for (BanquetAutoOpenSettleMember member : list) {
                            BanquetProto.SimpleMemberRewardTempMsg.Builder builder = BanquetProto.SimpleMemberRewardTempMsg.newBuilder();
                            builder.setName(member.getN());
                            builder.setRq(member.getRq());
                            settleBuild.addMemberReward(builder);
                        }
                    }
                    clientMsg.addSettle(settleBuild);
                }
            }
        }
        player.sendPacket(Protocol.U_BANQUET_ACTIVITY_AUTO_SETTLE_RESULT, clientMsg);
        return 0;
    }

    public static void syncAutoBanquetSettingInfo(GamePlayer player){
        long userId = player.getUserId();
        ActivityInfo activityInfo = NormalActivityMgr.getRunningCrossBanquetRankActivity();
        //必须是跨服争霸，就是三个区服的才能开宴会
        if(activityInfo != null && activityInfo.getServerIdList().size() > 2){
            UserAutoBanquetActivityData activityData = userAutoBanquetActivityDataMap.get(userId);
            if(activityData != null && activityData.getActivityId() == activityInfo.getActivityId()){
                BanquetProto.AutoBanquetSettingInfoTemp.Builder builder = getActivityDataBuilder(activityData);
                BanquetProto.AutoBanquetSettingInfoSyncMsg.Builder clientMsg = BanquetProto.AutoBanquetSettingInfoSyncMsg.newBuilder();
                clientMsg.setSetting(builder);
                player.sendPacket(Protocol.U_BANQUET_ACTIVITY_AUTO_INFO_SYNC, clientMsg);
            }
        }
    }

    private static Map<Long, Object> userLockerMap = new ConcurrentHashMap<>();

    public static Object getUserLocker(long userId){
        if(!userLockerMap.containsKey(userId)){
            synchronized (userLockerMap){
                if(!userLockerMap.containsKey(userId)){
                    userLockerMap.put(userId, new Object());
                }
            }
        }
        return userLockerMap.get(userId);
    }
}
